package notes.java.concurrent;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

/**
 * countDownLatch这个类使一个线程等待其他线程各自执行完毕后再执行。
 * 是通过一个计数器来实现的，计数器的初始值是线程的数量。每当一个线程执行完毕后，计数器的值就-1，当计数器的值为0时，表示所有线程都执行完毕，然后在闭锁上等待的线程就可以恢复工作了。
 * 
 * @author wangcs
 */
public class T1_TestCountDownLatch {

	// 现在要模拟一个并发程序，有5000个请求，并发量是200，对一个数值做加法计算，所有线程处理完后，打印出结果数

	// 请求数
	private static int clientReqNum = 5000;
	// 并发数
	private static int threadSize = 200;
	// 计数从0开始
	private static int count = 0;

	// 加法
	private static void add() {
		count++;
	}

	public static void main(String[] args) throws Exception {
		// 创建一个线程池
		ExecutorService excutorService = Executors.newCachedThreadPool();

		// 定义一个5000大小的计数器
		CountDownLatch countDownLatch = new CountDownLatch(clientReqNum);
		// 定义一个并发200的信号量
		Semaphore semaphore = new Semaphore(threadSize);

		// 启5000个线程
		for (int i = 0; i < clientReqNum; i++) {
			excutorService.execute(() -> {
				try {
					semaphore.acquire(); // 是否在200个并发量内，是就可以执行，不是就抛弃
					add(); // 加法处理
					semaphore.release();// 释放
					countDownLatch.countDown(); // 每运行一个线程后减1
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			});
		}

		// 等待所有线程运行完
		countDownLatch.await();
		// 关闭线程池
		excutorService.shutdown();
		// 打印结果
		System.out.println("count:" + count);
	}
}
